package tech.mhuang.pacebox.springboot.core.entity;

import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import tech.mhuang.pacebox.core.builder.BaseBuilder;

import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * RequestModel构造
 *
 * @author mhuang
 * @since 1.0.0
 */
public abstract class RequestModelBuilder<T> implements BaseBuilder<RequestModel<T>> {

    private RequestModel<T> requestModel;

    private final AtomicBoolean building = new AtomicBoolean();

    public RequestModelBuilder() {
        this.requestModel = new RequestModel<>();
    }

    public RequestModelBuilder<T> type(Type type) {
        this.requestModel.setType(type);
        return this;
    }

    public RequestModelBuilder<T> method(HttpMethod method) {
        this.requestModel.setMethod(method);
        return this;
    }

    public RequestModelBuilder<T> typeReference(ParameterizedTypeReference<T> typeReference) {
        this.requestModel.setTypeReference(typeReference);
        return this;
    }

    public RequestModelBuilder<T> mediaType(MediaType mediaType) {
        this.requestModel.setMediaType(mediaType);
        return this;
    }

    public RequestModelBuilder<T> url(String url) {
        this.requestModel.setUrl(url);
        return this;
    }

    public RequestModelBuilder<T> sufUrl(String sufUrl) {
        this.requestModel.setSufUrl(sufUrl);
        return this;
    }

    public RequestModelBuilder<T> param(String param) {
        this.requestModel.setParams(param);
        return this;
    }

    public RequestModelBuilder<T> headerParamMap(Map<String, String> headerParamMap) {
        this.requestModel.setHeaderParamMap(headerParamMap);
        return this;
    }

    public RequestModelBuilder<T> addHeader(Map<String, String> headerParamMap) {
        this.requestModel.getHeaderParamMap().putAll(headerParamMap);
        return this;
    }

    @Override
    public RequestModel<T> builder() {
        if (this.building.compareAndSet(false, true)) {
            this.requestModel = doBuild();
            return this.requestModel;
        }
        throw new RuntimeException("already request builder");
    }

    /**
     * 构建处理代码
     *
     * @return 构建对象
     */
    protected abstract RequestModel<T> doBuild();
}
